package com.tanhua.server.service;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.autoconfig.template.TXSMSTemplate;
import com.tanhua.commons.Constants;
import com.tanhua.commons.exception.TanHuaException;
import com.tanhua.commons.utils.JwtUtils;
import com.tanhua.dubbo.api.db.UserApi;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.dubbo.api.mongo.FriendApi;
import com.tanhua.dubbo.api.mongo.UserLikeApi;
import com.tanhua.dubbo.api.mongo.VisitorsApi;
import com.tanhua.model.db.User;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.Friend;
import com.tanhua.model.mongo.UserLike;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.*;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
public class Userservice {

    @Autowired
    private TXSMSTemplate txsmsTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @DubboReference
    private UserApi userApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private FriendApi friendApi;

    @DubboReference
    private UserLikeApi userLikeApi;

    @DubboReference
    private VisitorsApi visitorsApi;

    /**
     * 调用第三方发送验证码
     *
     * @param param
     */
    public void sendvalidate(Map<String, String> param) {
        String phone = param.get("phone");
        String key = "validate_code" + phone;
        String redisValidate = stringRedisTemplate.opsForValue().get(key);
        if (StringUtils.isNotEmpty(redisValidate)) {
            throw new TanHuaException(ErrorResult.duplicate());
        }
//        String validate = RandomUtil.randomNumbers(6);
//        txsmsTemplate.sendValidateCode(phone,validate);
        String validate = "123456";
        stringRedisTemplate.opsForValue().set(key, validate, 1, TimeUnit.MINUTES);

    }

    /**
     * 校验验证码是否正确
     */
    public Map<String, Object> login(Map<String, String> param) {
        String phone = param.get("phone");
        String verificationCode = param.get("verificationCode");
        String key = "validate_code" + phone;
        String redisValidate = stringRedisTemplate.opsForValue().get(key);
        if (!StringUtils.equals(verificationCode, redisValidate)) {
            throw new TanHuaException(ErrorResult.loginError());
        }
        stringRedisTemplate.delete(key);
        User user = userApi.findByMobile(phone);
        boolean isNew = false;
        if (user == null) {
            user = new User();
            user.setMobile(phone);
            String password = phone.substring(5);
            user.setPassword(DigestUtil.md5Hex(password));
            Long add = userApi.add(user);
            user.setId(add);
            isNew = true;
            if (huanXinTemplate.createUser(Constants.HX_USER_PREFIX + add, Constants.INIT_PASSWORD)) {
                User hxuser = new User();
                hxuser.setId(add);
                hxuser.setHxUser(Constants.HX_USER_PREFIX + add);
                hxuser.setHxPassword(Constants.INIT_PASSWORD);
                userApi.update(hxuser);
                user.setHxUser(Constants.HX_USER_PREFIX + add);
                user.setHxPassword(Constants.INIT_PASSWORD);
            }
        }
        UserHolder.setUser(user);
        String token = JwtUtils.createToken(user.getId(), phone);
        String userJSON = JSON.toJSONString(user);
        stringRedisTemplate.opsForValue().set("TOKEN_" + token, userJSON);
        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("isNew", isNew);

        return result;
    }

    public boolean checkVerificationCode(Map<String, String> verificationCode) {
        String Code = verificationCode.get("verificationCode");
        String phone = UserHolder.getUser().getMobile();
        String key = "validate_code" + phone;
        String redisValidate = stringRedisTemplate.opsForValue().get(key);
        if (!StringUtils.equals(Code, redisValidate)) {
            return false;
        }
        stringRedisTemplate.delete(key);
        return true;
    }

    public void updatePhone(Map<String, String> phone, String token) {
        //将当前登录的用户ID传过去
        phone.put("userid", String.valueOf(UserHolder.getUserId()));
        //删除旧手机号的token
        String key = "TOKEN_" + token;
        stringRedisTemplate.delete(key);
        userApi.updatePhone(phone);

    }

    /**
     * 是否喜欢
     *
     * @param uid
     * @return
     */
    public Boolean alreadyLove(Long uid) {
        String likeKey = Constants.USER_LIKE_KEY + UserHolder.getUserId();
        String notLikeKey = Constants.USER_LIKE_KEY + UserHolder.getUserId();
        if (stringRedisTemplate.opsForSet().isMember(likeKey, uid.toString())) {
            return true;
        }
        if (stringRedisTemplate.opsForSet().isMember(notLikeKey, uid.toString())) {
            return false;
        }
        return false;
    }

    /**
     * 查看互相喜欢
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult getFriends(Long page, Long pagesize) {
        PageResult<UserLike> loves = userLikeApi.getLoves(page, pagesize, UserHolder.getUserId());
        PageResult<UserLike> myLikeUsers = userLikeApi.getMyLikeUsers(page, pagesize, UserHolder.getUserId());
        List<UserLike> userLikes = loves.getItems();
        List<UserLike> myLikeUsersItems = myLikeUsers.getItems();
        List<Long> collect = new ArrayList<>();
        for (UserLike userLike : userLikes) {
            for (UserLike myLikeUsersItem : myLikeUsersItems) {
                if (userLike.getUserId() == myLikeUsersItem.getLikeUserId()) {
                    collect.add(userLike.getUserId());
                }

            }
        }
        List<UserInfo> userInfoList = userInfoApi.getUsersByid(collect);
        List<Friends> volList = new ArrayList<>();
        if (BeanUtil.isNotEmpty(userInfoList)){
            for (UserInfo userInfo : userInfoList) {
                if (BeanUtil.isEmpty(userInfo)) {
                    continue;
                }
                String loginLikeKey = Constants.USER_LIKE_KEY + UserHolder.getUserId();
                String userInfoLikeKey = Constants.USER_LIKE_KEY + userInfo.getId();

                if (stringRedisTemplate.opsForSet().isMember(loginLikeKey, userInfo.getId().toString())
                        && stringRedisTemplate.opsForSet().isMember(userInfoLikeKey, UserHolder.getUserId().toString())) {
                    Friends init = Friends.init(userInfo);
                    volList.add(init);
                }
            }
        }
        return new PageResult(page, pagesize, loves.getCounts() - myLikeUsers.getCounts(), volList);
    }

    /**
     * 获取喜欢列表
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult getLikeUser(Long page, Long pagesize) {
        PageResult<UserLike> result = userLikeApi.getMyLikeUsers(page, pagesize, UserHolder.getUserId());
        List<UserLike> items = result.getItems();
        List<Long> collect = items.stream().map(UserLike::getLikeUserId).collect(Collectors.toList());
        List<UserInfo> userInfos = userInfoApi.getUsersByid(collect);
        List<Friends> voList = new ArrayList<>();
        if (CollectionUtils.isEmpty(userInfos)) {
            throw new TanHuaException(null);
        }
        for (UserInfo userInfo : userInfos) {
            Friends init = Friends.init(userInfo);
            voList.add(init);
        }

        return new PageResult(page, pagesize, result.getCounts(), voList);
    }

    /**
     * 查询粉丝
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult getFriend(Long page, Long pagesize) {
        PageResult<UserLike> loves = userLikeApi.getLoves(page, pagesize, UserHolder.getUserId());
        List<UserLike> items = loves.getItems();
        List<Long> collect = items.stream().map(UserLike::getUserId).collect(Collectors.toList());
        List<UserInfo> userInfos = userInfoApi.getUsersByid(collect);
        List<Friends> voList = new ArrayList<>();
        if (CollectionUtils.isEmpty(userInfos)) {
            throw new TanHuaException(null);
        }
        for (UserInfo userInfo : userInfos) {
            Friends init = Friends.init(userInfo);
            if (!alreadyLove(userInfo.getId())) {
                init.setAlreadyLove(false);
            }
            voList.add(init);
        }
        return new PageResult(page, pagesize, loves.getCounts(), voList);
    }

    /**
     * 喜欢用户
     *
     * @param uid
     */
    public void addFriend(Long uid) {
        friendApi.addContacts(uid, UserHolder.getUserId());
        userLikeApi.loveUser(uid, UserHolder.getUserId());
        String likeKey = Constants.USER_LIKE_KEY + UserHolder.getUserId();
        String notlikeKey = Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId();
        if (stringRedisTemplate.opsForSet().isMember(notlikeKey, uid.toString())) {
            stringRedisTemplate.opsForSet().remove(notlikeKey, uid.toString());
        }
        stringRedisTemplate.opsForSet().add(likeKey, uid.toString());
        User byHxId = userApi.findByHxId(Constants.HX_USER_PREFIX + uid);
        if (userLikeApi.loveUser(uid, UserHolder.getUserId()) && BeanUtil.isNotEmpty(byHxId)) {
            huanXinTemplate.addContact(UserHolder.getUser().getHxUser(), uid.toString());
        }
    }

    /**
     * 取消喜欢
     *
     * @param uid
     */
    public void unLike(Long uid) {
        userLikeApi.notLikeUser(uid, UserHolder.getUserId());
        String likeKey = Constants.USER_LIKE_KEY + UserHolder.getUserId();
        String notLikeKey = Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId();
        stringRedisTemplate.opsForSet().remove(likeKey, uid.toString());
        stringRedisTemplate.opsForSet().add(notLikeKey, uid.toString());
    }

    /**
     * 查看访客列表
     * 记录用户查看 访客列表的时间
     */
    public PageResult visitors() {
        //记录用户查看 访客列表的时间
        String redisKey = Constants.VISITORS_USER;
        String whoKey = UserHolder.getUserId().toString();
        stringRedisTemplate.opsForHash().put(redisKey, whoKey, System.currentTimeMillis() + "");

        //查看访客列表
        PageResult<Visitors> result = visitorsApi.findAllVisit(UserHolder.getUserId());
        List<Visitors> items = result.getItems();
        List<Long> userIds = items.stream().map(Visitors::getVisitorUserId).collect(Collectors.toList());
        List<UserInfo> usersByid = userInfoApi.getUsersByid(userIds);
        List<Friends> friendsList = usersByid.stream().map(u -> Friends.init(u)).collect(Collectors.toList());
        for (Friends friends : friendsList) {
            Long userId = friends.getId();
            if (!alreadyLove(userId)) {
                friends.setAlreadyLove(false);
            }
        }
        return new PageResult(result.getPage(), result.getPagesize(), result.getCounts(), friendsList);
    }

    /**
     *  获取互相喜欢，喜欢，粉丝数
     * @return
     */
    public CountsVo getCounts() {
        CountsVo vo = userLikeApi.getCounts(UserHolder.getUserId());
        return vo;
    }
}
